#include "loaderwizardpage.h"
#include "ui_loaderwizardpage.h"

LoaderWizardPage::LoaderWizardPage(QWidget *parent) :
    QWizardPage(parent),
    m_ui(new Ui::LoaderWizardPage)
{
    m_ui->setupUi(this);
    m_ui->progressBar->setValue(0);
    m_ui->progressBar->setMaximum(0);

    connect(this,SIGNAL(subTaskFinished(int)),this,SLOT(onsubTaskFinished(int)));
    finished = false;
    completeChanged();
}

LoaderWizardPage::~LoaderWizardPage()
{
    delete m_ui;
}

void LoaderWizardPage::changeEvent(QEvent *e)
{
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void LoaderWizardPage::initializePage()
{
    StartAsyncLoad(0);
}

bool LoaderWizardPage::isComplete() const
{
    return finished;
}

void LoaderWizardPage::StartAsyncLoad(int step)
{
    worker.wait();
    switch(step)
    {
        case 0: //load matrix
        {
			if(indivFile.endsWith(tr(".mat")) && QFile::exists(indivFile))
			{
				worker.setFunction(this,&LoaderWizardPage::LoadMatrix);
				worker.setTaskDescription("Loading correlation matrix");
				worker.start();
				m_ui->progressLabel->setText(tr("Loading correlation matrix"));
			}
			else
				QMessageBox::warning(this,tr("File not found"),tr("The file could not be found."));
        } break;
        case 1: //load names
        {
            worker.setFunction(this,&LoaderWizardPage::LoadTemplateNames);
            worker.setTaskDescription("Loading template names");
            worker.start();
            m_ui->progressLabel->setText(tr("Loading template names"));
        } break;
        case 2: //load mask
        {
            m_ui->progressLabel->setText(tr("Loading template 3-D mask"));
            worker.setFunction(this,&LoaderWizardPage::LoadTemplate3DMask);
            worker.setTaskDescription("Loading template 3-D mask");
            worker.start();

        } break;
        case 3:
        {
            m_ui->progressLabel->setText(tr("Generating 3-D network links"));
            worker.setFunction(this,&LoaderWizardPage::LoadNetworkLinks);
            worker.setTaskDescription("Generating 3-D network links");
            worker.start();
        } break;
    }
}


void LoaderWizardPage::onsubTaskFinished(int lastTask)
{
    if(lastTask < 3)
        StartAsyncLoad(lastTask+1); //Start Next task
    else
    {
        finished = true;
        completeChanged();
    }
}

void LoaderWizardPage::onProgress(int val, int max)
{
    m_ui->progressBar->setMaximum(max);
    m_ui->progressBar->setValue(val);
}

void LoaderWizardPage::LoadMatrix()
{
	//load full matrix here (53 subjects) and calculate averages
	matrices = CorrelationMatrix::createListFromFile(indivFile.toStdString());
	/*else if(corrFile.endsWith(tr(".csv")))
		matrix.loadFromCSVFile(corrFile.toStdString());
	else
		throw std::exception("Unknown file extension");
	*/
	if(meanFile.length() == 0)
		calculateMean();
	else
		loadMean();

	if(medianFile.length() == 0)
		calculateMedian();
	else
		loadMedian();

    emit subTaskFinished(0);
}

void LoaderWizardPage::calculateMean()
{
	meanMatrix = new CorrelationMatrix();
	if(matrices.size()==0)
		return;

	for(unsigned int i = 0;i<matrices.at(0)->height();i++)
	{
		std::vector<double> vec;
		for(unsigned int j = 0;j<matrices.at(0)->width();j++)
		{
			double val = 0;;			
			for(int k = 0; k<matrices.count();k++)
				val+=matrices.at(k)->at(i,j);
			val/=(double)matrices.count();
			vec.push_back(val);
		}
		meanMatrix->addRow(vec);
	}
}

void LoaderWizardPage::calculateMedian()
{
}

void LoaderWizardPage::loadMean()
{
	meanMatrix = CorrelationMatrix::createFromFile(meanFile.toStdString());
}

void LoaderWizardPage::loadMedian()
{
	medianMatrix = CorrelationMatrix::createFromFile(medianFile.toStdString());
}


void LoaderWizardPage::LoadTemplateNames()
{
	aaltemplate.setNumberOfROIs(matrices.at(0)->width());

    connect(&aaltemplate,SIGNAL(taskUpdate(int,int)),this,SLOT(onProgress(int,int)));

#ifdef _DEBUG
	QString fPath(tr(DATA_ROOT)+tr("/exp.txt"));
#else
	QString fPath(QDir::currentPath()+"/Data/exp.txt");
#endif

	aaltemplate.loadNamesFromFile(fPath.toStdString());
    emit subTaskFinished(1);
}

void LoaderWizardPage::LoadTemplate3DMask()
{
    //aaltemplate.load3DdataFromHdrFile(maskFile.toStdString());
#ifdef _DEBUG
	QString fPath(tr(DATA_ROOT)+tr("/Regions"));
#else
	QString fPath(QDir::currentPath()+"/Data/Regions");
#endif
	aaltemplate.load3DdataFromVTIFiles(fPath.toStdString());
    emit subTaskFinished(2);
}

void LoaderWizardPage::LoadNetworkLinks()
{
    connect(&network,SIGNAL(taskUpdate(int,int)),this,SLOT(onProgress(int,int)));

    network.setTemplate(&aaltemplate);
	network.setCurrentAverageMatrix(meanMatrix);
	network.setCurrentIndividualMatrix(matrices.at(0));
	network.init();

    emit subTaskFinished(3);
}

void LoaderWizardPage::setIndividualsMatrixFile(QString file)
{
    indivFile = file;
}

void LoaderWizardPage::setMeanMatrixFile(QString file)
{
    meanFile = file;
}

void LoaderWizardPage::setMedianMatrixFile(QString file)
{
    medianFile = file;
}


CorrelationMatrix* LoaderWizardPage::GetMedianMatrix()
{
    return medianMatrix;
}

CorrelationMatrix* LoaderWizardPage::GetMeanMatrix()
{
    return meanMatrix;
}

QVector<CorrelationMatrix*>& LoaderWizardPage::GetIndividualsMatrices() const
{
	return const_cast<QVector<CorrelationMatrix*>&>(matrices);
}

AnatomicalTemplate* LoaderWizardPage::GetTemplate()
{
    return &aaltemplate;
}

FunctionalNetwork* LoaderWizardPage::GetNetwork()
{
    return &network;
}
